package com.huiminpay.merchant.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.domain.PageVO;
import com.huiminpay.common.cache.util.PhoneUtil;
import com.huiminpay.common.cache.util.StringUtil;
import com.huiminpay.merchant.api.MerchantService;
import com.huiminpay.merchant.convert.MerchantConvert;
import com.huiminpay.merchant.convert.StaffConvert;
import com.huiminpay.merchant.convert.StoreConvert;
import com.huiminpay.merchant.dto.MerchantDTO;
import com.huiminpay.merchant.dto.StaffDTO;
import com.huiminpay.merchant.dto.StoreDTO;
import com.huiminpay.merchant.entity.Merchant;
import com.huiminpay.merchant.entity.Staff;
import com.huiminpay.merchant.entity.Store;
import com.huiminpay.merchant.entity.StoreStaff;
import com.huiminpay.merchant.mapper.MerchantMapper;
import com.huiminpay.merchant.mapper.StaffMapper;
import com.huiminpay.merchant.mapper.StoreMapper;
import com.huiminpay.merchant.mapper.StoreStaffMapper;
import com.huiminpay.user.api.TenantService;
import com.huiminpay.user.api.dto.tenant.CreateTenantRequestDTO;
import com.huiminpay.user.api.dto.tenant.TenantDTO;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * @Author: yz
 * @Date: 2024/7/17 19:23
 */
@Service //发布dubbo服务
public class MerchantServiceImpl implements MerchantService {
    @Resource
    MerchantMapper merchantMapper;
    @Resource
    StoreMapper storeMapper;
    @Resource
    StaffMapper staffMapper;
    @Resource
    StoreStaffMapper storeStaffMapper;


    @Reference //发现dubbo服务
    TenantService tenantService;

    /**
     * 根据主键查询商户信息
     *
     * @param id
     * @return
     */
    @Override
    public MerchantDTO MerchantById(Long id) {
        Merchant merchant = merchantMapper.selectById(id);
        MerchantDTO merchantDTO = MerchantConvert.INSTANCE.entity2DTO(merchant);
        return merchantDTO;
        /*if (merchant != null) {
            MerchantDTO merchantDTO = new MerchantDTO();
            merchantDTO.setId(merchant.getId());
            merchantDTO.setMerchantName(merchant.getMerchantName());
            merchantDTO.setMerchantNo(merchant.getMerchantNo());
            merchantDTO.setMerchantAddress(merchant.getMerchantAddress());
            return merchantDTO;
        }
        return null;*/
    }


    /**
     * 注册商户服务接口，接收账号、密码、手机号，为了可扩展性使用merchantDto接收数据
     * 调用SaaS接口： 新增租户 用户 绑定租户和用户的关系 初始化权限
     *
     * @param merchantDTO 商户注册信息
     * @return 注册成功的商户信息
     */
    @Override
    @Transactional
    public MerchantDTO createMerchant(MerchantDTO merchantDTO) throws BusinessException {
       /* Merchant merchant = new Merchant();
        merchant.setMobile(merchantDTO.getMobile());
        merchant.setUsername(merchantDTO.getUsername());
        merchant.setAuditStatus("0");*/
        //合法性判断

        if (merchantDTO == null) {
            throw new BusinessException(CommonErrorCode.E_100108);
        }
        if (StringUtil.isBlank(merchantDTO.getMobile())) {
            throw new BusinessException(CommonErrorCode.E_100112);
        }
        if (!PhoneUtil.isMatches(merchantDTO.getMobile())) {
            throw new BusinessException(CommonErrorCode.E_100109);
        }
        //唯一性
        Integer count = merchantMapper.selectCount(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getMobile, merchantDTO.getMobile()));
        if (count > 0) {
            throw new BusinessException(CommonErrorCode.E_100113);
        }
        //用户名空判断
        if (StringUtil.isBlank(merchantDTO.getUsername())) {
            throw new BusinessException(CommonErrorCode.E_100110);
        }
        //密码空判断
        if (StringUtil.isBlank(merchantDTO.getPassword())) {
            throw new BusinessException(CommonErrorCode.E_100111);
        }

        //2.调用SaaS接口 添加 租户并绑定和门店 员工 商户之间的关系

         /*1、手机号
         2、账号
         3、密码
         4、租户类型：huimin-merchant
         5、默认套餐：huimin-merchant
         6、租户名称，同账号名*/
        CreateTenantRequestDTO request = new CreateTenantRequestDTO(); //新增租户
        request.setName(merchantDTO.getUsername());
        request.setTenantTypeCode("huimin-merchant");
        request.setBundleCode("huimin-merchant");
        request.setMobile(merchantDTO.getMobile());
        request.setPassword(merchantDTO.getPassword());
        request.setUsername(merchantDTO.getUsername());
        TenantDTO tenantDTO = tenantService.createTenantAndAccount(request);

        //一个商户对应一个租户
        Integer count1 = merchantMapper.selectCount(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getTenantId, tenantDTO.getId()
                ));
        if (count1 > 0) {
            throw new BusinessException(CommonErrorCode.E_200017);
        }

        Long id = tenantDTO.getId(); //租户id
        //dto转entity
        Merchant merchant = MerchantConvert.INSTANCE.DTO2Entity(merchantDTO);
        merchant.setAuditStatus("0");
        //设置租户id
        merchant.setTenantId(id);//商户设置租户id

        int insert = merchantMapper.insert(merchant); //主键自动生成
//        merchantDTO.setId(merchant.getId()); //回填主键
        //新增跟门店
        StoreDTO storeDTO = new StoreDTO();
        storeDTO.setMerchantId(merchant.getId());
        storeDTO.setStoreStatus(true);
        storeDTO.setStoreName("跟门店");
        storeDTO.setStoreNumber(666L);
        storeDTO.setStoreAddress("电子产业园");
        StoreDTO store = createStore(storeDTO);
        //新增员工
        StaffDTO staffDTO = new StaffDTO();
        staffDTO.setMerchantId(merchant.getId());
        /*staffDTO.setFullName("");
        staffDTO.setPosition("");*/
        staffDTO.setUsername(merchantDTO.getUsername());
        staffDTO.setMobile(merchant.getMobile());
        staffDTO.setStoreId(store.getId());
        staffDTO.setLastLoginTime(LocalDateTime.now());
        staffDTO.setStaffStatus(true);
        StaffDTO staff = createStaff(staffDTO);
        //设置管理员绑定关系
        createStoreStaff(store.getId(), staff.getId());
        return MerchantConvert.INSTANCE.entity2DTO(merchant);
    }

    /**
     * 资质申请接口
     *
     * @param merchantId  商户id
     * @param merchantDTO 资质申请的信息
     * @throws BusinessException
     */
    @Override
    public void applyMerchant(Long merchantId, MerchantDTO merchantDTO) throws BusinessException {
        //合法性校验 参数不能为空
        if (merchantId == null || merchantDTO == null) {
            throw new BusinessException(CommonErrorCode.E_300009);
        }
        Merchant merchant = merchantMapper.selectById(merchantId);
        //商户不能为空
        if (merchant == null) {
            throw new BusinessException(CommonErrorCode.E_200002); //商户不存在
        }
        //  前端传递+主键查询信息=完整的信息
        Merchant entity = MerchantConvert.INSTANCE.DTO2Entity(merchantDTO);
        entity.setId(merchantId);
        entity.setUsername(merchant.getUsername());
        entity.setMobile(merchant.getMobile());
        entity.setAuditStatus("1");//修改状态
        entity.setTenantId(merchant.getTenantId());//租户id
        merchantMapper.updateById(entity);
    }

    /**
     * 商户资质审核通过新增门店
     *
     * @param storeDTO
     * @return
     * @throws BusinessException
     */
    @Override
    public StoreDTO createStore(StoreDTO storeDTO) throws BusinessException {
        Store store = StoreConvert.INSTANCE.dto2entity(storeDTO);
        storeMapper.insert(store);
        return StoreConvert.INSTANCE.entity2dto(store);
    }

    /**
     * 新增员工
     *
     * @param staffDTO
     * @return
     * @throws BusinessException
     */
    @Override
    public StaffDTO createStaff(StaffDTO staffDTO) throws BusinessException {
        if (staffDTO == null) {
            throw new BusinessException(CommonErrorCode.E_300009);
        }
        //同一商户下，用户名不能重复
        if (StringUtil.isBlank(staffDTO.getUsername())) {
            throw new BusinessException(CommonErrorCode.E_100110);
        }
        if (isExistUsernameOnMerchant(staffDTO.getUsername(), staffDTO.getMerchantId())) {
            throw new BusinessException(CommonErrorCode.E_100114);
        }
        //同一商户下，手机号不能重复
        if (StringUtil.isBlank(staffDTO.getMobile())) {
            throw new BusinessException(CommonErrorCode.E_100112);
        }
        if (isExistMobileOnMerchant(staffDTO.getMobile(), staffDTO.getMerchantId())) {
            throw new BusinessException(CommonErrorCode.E_100113);
        }


        Staff staff = StaffConvert.INSTANCE.dto2entity(staffDTO);
        staffMapper.insert(staff);
        return StaffConvert.INSTANCE.entity2dto(staff);
    }

    /**
     * 根据手机号和商户id查询员工是否存在
     *
     * @param mobile
     * @param merchantId
     * @return
     */
    private boolean isExistMobileOnMerchant(String mobile, Long merchantId) {
        Integer i = staffMapper.selectCount(new LambdaQueryWrapper<Staff>()
                .eq(Staff::getMobile, mobile)
                .eq(Staff::getMerchantId, merchantId)
        );
        return i > 0;
    }

    /**
     * 根据姓名和商户id查询员工是否存在
     *
     * @param username
     * @param merchantId
     * @return
     */
    private boolean isExistUsernameOnMerchant(String username, Long merchantId) {
        Integer i = staffMapper.selectCount(new LambdaQueryWrapper<Staff>()
                .eq(Staff::getUsername, username)
                .eq(Staff::getMerchantId, merchantId)
        );
        return i > 0;
    }


    /**
     * 添加门店和员工绑定关系
     *
     * @param storeId
     * @param staffId
     * @throws BusinessException
     */
    @Override
    public void createStoreStaff(Long storeId, Long staffId) throws BusinessException {
        StoreStaff storeStaff = new StoreStaff();
        storeStaff.setStoreId(storeId);
        storeStaff.setStaffId(staffId);
        storeStaffMapper.insert(storeStaff);
    }

    /**
     * 根据租户id查询商户的信息
     *
     * @param tenantId
     * @return
     */
    @Override
    public MerchantDTO queryMerchantByTenantId(Long tenantId) throws BusinessException {
        Merchant merchant = merchantMapper.selectOne(new LambdaQueryWrapper<Merchant>()
                .eq(Merchant::getTenantId, tenantId));
        return MerchantConvert.INSTANCE.entity2DTO(merchant);
    }

    /**
     * 分页条件查询商户下的门店
     *
     * @param storeDTO 查询条件
     * @param pageNum  当前页
     * @param pageSize 页大小
     * @return 门店列表
     */
    @Override
    public PageVO<StoreDTO> queryStoreByPage(StoreDTO storeDTO, Integer pageNum, Integer pageSize) {
        //1、创建分页对象
        Page<Store> page = new Page<>(pageNum, pageSize);

        //2、创建查询条件
        LambdaQueryWrapper<Store> queryWrapper = new LambdaQueryWrapper<>();
        if (storeDTO != null && storeDTO.getMerchantId() != null) {
            queryWrapper.eq(Store::getMerchantId, storeDTO.getMerchantId());
        }
        //3、执行分页查询
        IPage<Store> storeIPage = storeMapper.selectPage(page, queryWrapper);
        //4、entity list转dto list
        List<StoreDTO> storeDTOS = StoreConvert.INSTANCE.listentity2dto(storeIPage.getRecords());
        //5、封装分页对象
        return new PageVO<>(storeDTOS, storeIPage.getTotal(), pageNum, pageSize);
    }

    /**
     * 查询门店是否属于某商户
     *
     * @param storeId    门店id
     * @param merchantId 商户id
     * @return 门店是否属于商户 true 属于 false 不属于
     */
    @Override
    public Boolean queryStoreInMerchant(Long storeId, Long merchantId) {
        Integer count = storeMapper.selectCount(new LambdaQueryWrapper<Store>()
                .eq(Store::getId, storeId).eq(Store::getMerchantId, merchantId));
        return count > 0;
    }


}
